<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 合同续约模型
 * 管理合同续约记录
 */
class ContractRenewal extends Model
{
    use HasFactory;

    /**
     * 表名
     */
    protected $table = 'contract_renewals';

    /**
     * 可填充字段
     */
    protected $fillable = [
        'contract_id',
        'employee_id',
        'original_contract_number',
        'renewal_type',
        'renewal_number',
        'renewal_reason',
        'new_start_date',
        'new_end_date',
        'extension_months',
        'is_open_ended',
        'previous_salary',
        'new_salary',
        'salary_adjustment_percentage',
        'salary_adjustment_reason',
        'previous_position',
        'new_position',
        'position_change_reason',
        'benefits_changes',
        'responsibilities_changes',
        'working_condition_changes',
        'proposed_by',
        'proposed_at',
        'approved_by',
        'approved_at',
        'approval_notes',
        'signed_by_employee',
        'signed_by_employee_date',
        'signed_by_company',
        'signed_by_company_date',
        'status',
        'rejection_reason',
        'effective_date',
        'attachments',
        'notes',
        'additional_terms',
    ];

    /**
     * 字段类型转换
     */
    protected $casts = [
        'new_start_date' => 'date',
        'new_end_date' => 'date',
        'proposed_at' => 'date',
        'approved_at' => 'date',
        'signed_by_employee_date' => 'date',
        'signed_by_company_date' => 'date',
        'effective_date' => 'date',
        'is_open_ended' => 'boolean',
        'extension_months' => 'integer',
        'renewal_number' => 'integer',
        'previous_salary' => 'decimal:2',
        'new_salary' => 'decimal:2',
        'salary_adjustment_percentage' => 'decimal:2',
        'benefits_changes' => 'array',
        'responsibilities_changes' => 'array',
        'working_condition_changes' => 'array',
        'attachments' => 'array',
        'additional_terms' => 'array',
    ];

    /**
     * 日期字段
     */
    protected $dates = [
        'new_start_date',
        'new_end_date',
        'proposed_at',
        'approved_at',
        'signed_by_employee_date',
        'signed_by_company_date',
        'effective_date',
        'created_at',
        'updated_at',
    ];

    // ============ 常量定义 ============

    public const TYPE_AUTOMATIC = 'automatic';
    public const TYPE_MANUAL = 'manual';
    public const TYPE_EARLY_RENEWAL = 'early_renewal';

    public const STATUS_DRAFT = 'draft';
    public const STATUS_APPROVED = 'approved';
    public const STATUS_REJECTED = 'rejected';
    public const STATUS_SIGNED = 'signed';
    public const STATUS_ACTIVE = 'active';

    // ============ 关联关系 ============

    /**
     * 关联原合同
     */
    public function contract(): BelongsTo
    {
        return $this->belongsTo(Contract::class);
    }

    /**
     * 关联员工
     */
    public function employee(): BelongsTo
    {
        return $this->belongsTo(Employee::class);
    }

    // ============ 访问器 ============

    /**
     * 获取续约类型标签
     */
    public function getRenewalTypeLabelAttribute(): string
    {
        return match($this->renewal_type) {
            self::TYPE_AUTOMATIC => '自动续约',
            self::TYPE_MANUAL => '手动续约',
            self::TYPE_EARLY_RENEWAL => '提前续约',
            default => $this->renewal_type ?? '未知'
        };
    }

    /**
     * 获取状态标签
     */
    public function getStatusLabelAttribute(): string
    {
        return match($this->status) {
            self::STATUS_DRAFT => '草稿',
            self::STATUS_APPROVED => '已批准',
            self::STATUS_REJECTED => '已驳回',
            self::STATUS_SIGNED => '已签署',
            self::STATUS_ACTIVE => '生效中',
            default => $this->status ?? '未知'
        };
    }

    /**
     * 获取新合同期限
     */
    public function getNewContractPeriodAttribute(): string
    {
        if ($this->is_open_ended) {
            return '无固定期限';
        }

        if ($this->new_start_date && $this->new_end_date) {
            $months = $this->new_start_date->diffInMonths($this->new_end_date);
            $years = floor($months / 12);
            $remainingMonths = $months % 12;

            if ($years > 0 && $remainingMonths > 0) {
                return "{$years}年{$remainingMonths}个月";
            } elseif ($years > 0) {
                return "{$years}年";
            } else {
                return "{$months}个月";
            }
        }

        return '未设置';
    }

    /**
     * 获取薪资调整信息
     */
    public function getSalaryAdjustmentInfoAttribute(): string
    {
        if (!$this->previous_salary || !$this->new_salary) {
            return '无调整';
        }

        $difference = $this->new_salary - $this->previous_salary;
        $percentage = $this->salary_adjustment_percentage;

        if ($difference > 0) {
            return "上调 {$percentage}% (+{$difference})";
        } elseif ($difference < 0) {
            return "下调 {$percentage}% ({$difference})";
        } else {
            return '无变化';
        }
    }

    /**
     * 获取是否已生效
     */
    public function getIsEffectiveAttribute(): bool
    {
        return $this->status === self::STATUS_ACTIVE
            && $this->effective_date
            && now()->isAfter($this->effective_date);
    }

    /**
     * 获取续约进度
     */
    public function getProgressAttribute(): string
    {
        $steps = [
            'proposed' => $this->proposed_at ? '已提议' : '未提议',
            'approved' => $this->approved_at ? '已批准' : '待批准',
            'signed' => $this->signed_by_employee_date && $this->signed_by_company_date ? '已签署' : '待签署',
            'effective' => $this->is_effective ? '已生效' : '待生效',
        ];

        $currentStep = '';
        foreach ($steps as $step => $status) {
            if ($status === '已生效') {
                $currentStep = '已完成';
                break;
            } elseif ($status === '待生效') {
                $currentStep = '待生效';
                break;
            } elseif ($status === '待签署') {
                $currentStep = '待签署';
                break;
            } elseif ($status === '待批准') {
                $currentStep = '待批准';
                break;
            }
        }

        return $currentStep ?: '未开始';
    }

    // ============ 作用域 ============

    /**
     * 已批准作用域
     */
    public function scopeApproved($query)
    {
        return $query->where('status', self::STATUS_APPROVED);
    }

    /**
     * 已生效作用域
     */
    public function scopeEffective($query)
    {
        return $query->where('status', self::STATUS_ACTIVE)
                    ->where('effective_date', '<=', now());
    }

    /**
     * 按续约类型筛选作用域
     */
    public function scopeByType($query, $type)
    {
        return $query->where('renewal_type', $type);
    }

    /**
     * 按状态筛选作用域
     */
    public function scopeByStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 待处理作用域
     */
    public function scopePending($query)
    {
        return $query->whereIn('status', [self::STATUS_DRAFT, self::STATUS_APPROVED, self::STATUS_SIGNED]);
    }

    // ============ 业务方法 ============

    /**
     * 批准续约
     */
    public function approve(string $approvedBy, ?string $notes = null): bool
    {
        $this->status = self::STATUS_APPROVED;
        $this->approved_by = $approvedBy;
        $this->approved_at = now();
        $this->approval_notes = $notes;

        return $this->save();
    }

    /**
     * 驳回续约
     */
    public function reject(string $approvedBy, string $reason): bool
    {
        $this->status = self::STATUS_REJECTED;
        $this->approved_by = $approvedBy;
        $this->approved_at = now();
        $this->rejection_reason = $reason;

        return $this->save();
    }

    /**
     * 签署续约
     */
    public function sign(array $signData): bool
    {
        if (isset($signData['signed_by_employee'])) {
            $this->signed_by_employee = $signData['signed_by_employee'];
            $this->signed_by_employee_date = now();
        }

        if (isset($signData['signed_by_company'])) {
            $this->signed_by_company = $signData['signed_by_company'];
            $this->signed_by_company_date = now();
        }

        if ($this->signed_by_employee_date && $this->signed_by_company_date) {
            $this->status = self::STATUS_SIGNED;
        }

        return $this->save();
    }

    /**
     * 生效续约
     */
    public function makeEffective(): bool
    {
        $this->status = self::STATUS_ACTIVE;
        $this->effective_date = now();

        return $this->save();
    }

    /**
     * 添加附件
     */
    public function addAttachment(array $attachment): bool
    {
        $attachments = $this->attachments ?? [];
        $attachments[] = $attachment;

        $this->attachments = $attachments;
        return $this->save();
    }

    /**
     * 移除附件
     */
    public function removeAttachment(string $attachmentId): bool
    {
        $attachments = $this->attachments ?? [];
        $attachments = array_filter($attachments, fn($attachment) => $attachment['id'] !== $attachmentId);

        $this->attachments = array_values($attachments);
        return $this->save();
    }

    // ============ 静态方法 ============

    /**
     * 获取续约类型选项
     */
    public static function getRenewalTypeOptions(): array
    {
        return [
            self::TYPE_AUTOMATIC => '自动续约',
            self::TYPE_MANUAL => '手动续约',
            self::TYPE_EARLY_RENEWAL => '提前续约',
        ];
    }

    /**
     * 获取状态选项
     */
    public static function getStatusOptions(): array
    {
        return [
            self::STATUS_DRAFT => '草稿',
            self::STATUS_APPROVED => '已批准',
            self::STATUS_REJECTED => '已驳回',
            self::STATUS_SIGNED => '已签署',
            self::STATUS_ACTIVE => '生效中',
        ];
    }

    /**
     * 计算续约薪资
     */
    public static function calculateRenewalSalary(
        float $currentSalary,
        float $adjustmentPercentage,
        ?string $adjustmentType = 'percentage'
    ): float {
        if ($adjustmentType === 'percentage') {
            return round($currentSalary * (1 + $adjustmentPercentage / 100), 2);
        }

        return $currentSalary;
    }

    /**
     * 验证续约数据
     */
    public static function validateRenewalData(array $data): array
    {
        $errors = [];

        // 必填字段验证
        $requiredFields = ['contract_id', 'employee_id', 'renewal_type', 'new_start_date'];
        foreach ($requiredFields as $field) {
            if (empty($data[$field])) {
                $errors[] = "{$field} 字段不能为空";
            }
        }

        // 续约类型验证
        $validTypes = array_keys(self::getRenewalTypeOptions());
        if (!empty($data['renewal_type']) && !in_array($data['renewal_type'], $validTypes)) {
            $errors[] = "无效的续约类型";
        }

        // 状态验证
        $validStatuses = array_keys(self::getStatusOptions());
        if (!empty($data['status']) && !in_array($data['status'], $validStatuses)) {
            $errors[] = "无效的状态";
        }

        // 时间验证
        if (!empty($data['new_start_date']) && !empty($data['new_end_date'])) {
            $startDate = strtotime($data['new_start_date']);
            $endDate = strtotime($data['new_end_date']);

            if ($startDate && $endDate && $startDate >= $endDate) {
                $errors[] = "新合同结束日期必须晚于开始日期";
            }
        }

        // 薪资验证
        if (!empty($data['new_salary']) && (!is_numeric($data['new_salary']) || $data['new_salary'] <= 0)) {
            $errors[] = "新薪资必须是有效的正数";
        }

        if (!empty($data['salary_adjustment_percentage']) && (!is_numeric($data['salary_adjustment_percentage']) || abs($data['salary_adjustment_percentage']) > 100)) {
            $errors[] = "薪资调整百分比必须在-100到100之间";
        }

        return $errors;
    }
}
